package com.chuangke.lowcode.component.flow;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.chuangke.common.exception.ChuangkeException;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.flow.domain.FlowFormModel;
import com.chuangke.flow.domain.OrderModel;
import com.chuangke.flow.service.FlowInstanceService;
import com.chuangke.lowcode.LowCodeContext;
import com.chuangke.lowcode.component.ProgressComponent;

import cn.hutool.core.util.StrUtil;

@Component
@Transactional(rollbackFor = Throwable.class)
public class FlowStartComponent implements ProgressComponent {

    @Autowired
    private FlowInstanceService flowInstanceService;

    @SuppressWarnings("unchecked")
    public void process(LowCodeContext modelContext) {
        if(StrUtil.isEmpty(modelContext.getFlowId())){
            throw new ChuangkeException("流程ID不能为空");
        }

        List<OrderModel> ffmList = (List<OrderModel>) modelContext.getDatas().stream().map(data -> {
            OrderModel handler = new FlowFormModel();
            try {
                /*初始化流程bean*/
                Map<String, String> flowModelFeildMapping = modelContext.getFlowModelFeildMapping();
                for (String flowColumn : flowModelFeildMapping.keySet()) {
                    BeanUtils.setProperty(handler, flowColumn,
                            BeanUtils.getProperty(data, flowModelFeildMapping.get(flowColumn)));
                }
                handler.setOrderCreatedAt(new Date());
                handler.setOrderCreatedBy(SecurityUtils.getUserId());
                handler.setOrderService(modelContext.getFlowServiceClass()==null? 
                		modelContext.getEntityModel().getServiceBeanName():
                	modelContext.getFlowServiceClass().getName());

                /*初始化流程变量*/
                List<String> flowVarList = modelContext.getFlowVarList();
                Map<String, Object> flowVariables = new HashMap<>();
                for (String flowVar : flowVarList) {
                    flowVariables.put(flowVar, BeanUtils.getProperty(data, flowModelFeildMapping.get(flowVar)));
                }

                handler.setVariables(flowVariables);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                throw new ChuangkeException(e);
            }
            return handler;
        }).collect(Collectors.toList());

        flowInstanceService.startInstanceByFlowId(modelContext.getFlowId(), ffmList);
    }

}
